Medium
Given an array of asynchronous functions functions
, return a new promise promise
. Each function in the array accepts no arguments and returns a promise. All the promises should be executed in parallel.
promise
resolves:
functions
were resolved successfully in parallel. The resolved value of promise
should be an array of all the resolved values of promises in the same order as they were in the functions
. The promise
should resolve when all the asynchronous functions in the array have completed execution in parallel.promise
rejects:
Please solve it without using the built-in Promise.all
function.
給定一個異步函數functions
陣列,傳回一個新的Promisepromise
。
數組中的每個函數不接受任何參數並傳回一個Promise。 所有Promise應該並行執行。
promise
解析:
functions
陣列返回的所有Promise都成功完成解析時。promise
的解析值應該是一個包含所有 Promise 解析值的數組,其順序與它們在 functions
中的順序相同。promise
。promise
拒絕:
請在不使用內建Promise.all
函數的情況下解決該問題。
var promiseAll = function(functions) {
return new Promise((resolve, reject) => {
const results = []; //解析functions數組的邏輯
for (let i = 0; i < functions.length; i++) {
functions[i]()
//Promise resolve的情況 使用.then(result=>{...})處理promise執行結果
.then(result => { })
//Promise reject的情況 使用.catch(error => { ... })處理promise錯誤信息
.catch(error => { });
}
});
};
解析functions
陣列並將結果存入results
陣列
外部宣告變數resolvedCount來記錄目前results
內已成功解析的 Promise 數量,
當已成功解析的 Promise 數量與原function陣列元素數量相等,
表示已全數解析完畢,使用 resolve() 返回結果。
當從“functions”返回的任何承諾被拒絕時。 “promise”也應該拒絕並給出第一次拒絕的理由。
var promiseAll = function(functions) {
return new Promise((resolve, reject) => {
const results = [];
let resolvedCount = 0;
//解析functions數組的邏輯
for (let i = 0; i < functions.length; i++) {
functions[i]()
.then(result => {
results[i] = result;
resolvedCount++;
if (resolvedCount === functions.length) { resolve(results);}
})
.catch(error => {
console.log(`發生錯誤: ${error}`);
reject(error);
});
}
});
};
因為.then 處理程序是非同步的,不會等待上個Promise是否已經解析成功。
//錯誤範例
var promiseAll = function(functions) {
return new Promise((resolve, reject) => {
const results = [];
for (let i = 0; i < functions.length; i++) {
functions[i]()
.then(result => {
results[i] = result;
if (results.length === functions.length) { resolve(results);}
})
.catch(error => {reject(error);});
}
});
};
以下面Input為例
Input: functions = [
() => new Promise(resolve => setTimeout(() => resolve(4), 50)),
() => new Promise(resolve => setTimeout(() => resolve(10), 150)),
() => new Promise(resolve => setTimeout(() => resolve(16), 100))
]
functions[1] 的解析時間比 functions[2] 長,當functions[2] 解析,並將結果存入 results[2]。
在 JavaScript 中,當你為數組的某個索引位置賦值時,
如果該索引超出了當前數組的長度,JavaScript 會自動擴展數組的長度以容納這個新元素。
這意味著數組的長度會根據最大的索引值來確定。
const ary = [];
ary[0] = 1;
ary[3] = 2;
在這個範例中,陣列的長度是 4,因為最大的索引是 3,所以長度是 3 + 1 = 4。
[1, undefined, undefined, 2]
所以functions[1]還沒解析完畢前,results陣列就會因為functions[2]解析完畢而擴展。
let start = Date.now();
async function testcase(functions){
let returnAry = await promiseAll(functions);
let end = Date.now();
let result ={
"t":end-start,
"resolved":returnAry,
}
console.log(result);
console.log(`returnAry: [${returnAry}]`);
}
let functions1 = [
() => new Promise(resolve => setTimeout(() => resolve(5), 200))
]
testcase(functions1);
//輸出
//{t: 210, resolved: Array(1)}
//returnAry: [5]
let functions2 = [
() => new Promise(resolve => setTimeout(() => resolve(1), 200)),
() => new Promise((resolve, reject) => setTimeout(() => reject("Error"), 100))
]
testcase(functions2);
// 輸出
// 發生錯誤: Error
// Uncaught Error UnhandledPromiseRejection:...
let functions3 = [
() => new Promise(resolve => setTimeout(() => resolve(4), 50)),
() => new Promise(resolve => setTimeout(() => resolve(10), 150)),
() => new Promise(resolve => setTimeout(() => resolve(16), 100))
]
testcase(functions3);
// 輸出
// {t: 161, resolved: Array(3)}
// returnAry: [4,10,16]